<?php

/**
 * 获取分类
 */
function getCate($name, $attr = null)
{
    $cate = M('category')->where(array(
        is_numeric($name) ? 'id' : 'name' => $name
    ))->find();
    return $attr ? $cate[$attr] : $cate;
}

/**
 * 获取所有子分类 id 列表
 */
function getSubCateIds($id, $withSelf = true)
{
    $id = (string)$id;
    $ids = $withSelf ? array(
        $id
    ) : array();
    $subCate = M('category')->where(array(
        'pid' => $id
    ))->select();

    if ($subCate) {
        foreach ($subCate as $v) {
            $ids[] = $v['id'];
            $ids = array_merge($ids, getSubCateIds($v['id'], $withSelf));
        }
    }
    return array_unique($ids);
}

/**
 * 获取下级分类列表
 */
function getSubCate($name)
{
    $id = getCate($name, 'id');
    return M('category')->where(array(
        'pid' => $id
    ))->select();
}

/**
 * 获取第n级父分类
 */
function getPCate($cate, $level = 1, $attr)
{
    $cates = getPCates($cate);
    $cate = $cates[count($cates) - $level];
    return $attr ? $cate[$attr] : $cate;
}

/**
 * 获取所有父分类
 */
function getPCates($cate, $init = true)
{
    static $chain;
    if ($init) {
        $chain = array();
    }
    $category = getCate($cate);
    $chain[] = $category;
    if ($category['pid'] != 0) {
        getPCates($category['pid'], false);
    }
    return $chain;
}

/**
 * 获取子分类
 */
function getSCate($name)
{
    return M('category')->where(array(
        'pid' => getCate($name, 'id')
    ))->order('sort ASC, id DESC')->select();
}

/**
 * 清理缓存目录及文件
 */
function delDirAndFile($dirName, $delDir = false)
{
    // 定义静态日志字符串
    static $log;
    // 打开文件地址
    if ($handle = opendir("$dirName")) {
        // 判断读取的文件是否有下级目录
        while (false !== ($item = readdir($handle))) {
            if ($item != "." && $item != ".." && $item != '.gitignore') {
                // 如果有下级目录循环执行函数
                if (is_dir("$dirName/$item")) {
                    delDirAndFile("$dirName/$item", $delDir);
                } else {
                    // 删除文件并输出日志
                    if (unlink("$dirName/$item"))
                        $log .= "成功删除文件： $dirName/$item<br />";
                }
            }
        }
        // 关闭路径
        closedir($handle);
        // 删除目录
        if ($delDir) {
            rmdir($dirName);
            $log .= "成功删除目录： $dirName<br />";
        }
    }
    return $log;
}

/**
 * 截取字符串长度，处理标签空格等转化成文本格式
 */
function str_cut($str, $num)
{
    $shotcut = preg_replace("/<\/?[^>]+>/i", '', $str);
    $shotcut = str_replace(array(
        ' ',
        '　',
        "\n"
    ), ' ', $shotcut);
    $shotcut = str_replace('&nbsp;', ' ', $shotcut);
    $shotcut = str_replace(array(
        'nbsp;',
        '&amp;',
        '&nbsp',
        '&amp;nbsp;'
    ), ' ', $shotcut);
    $shotcut = preg_replace('/\s+/', ' ', $shotcut);

    $cutstr = mb_substr($shotcut, 0, $num, 'UTF-8');
    $str = $cutstr . (strlen($shotcut) > $num ? '...' : '');

    return $str;
}

/**
 * 处理中文及引文空格
 */
function trimBlankChars($data)
{
    if (is_array($data)) {
        foreach ($data as $_key => $_value) {
            $data[$_key] = trimBlankChars($_value);
        }
    } else {
        // 处理收尾中文全角空格
        $data = preg_replace('/^(　|\s)*|(　|\s)*$/', '', $data);
    }

    return $data;
}

/**
 * 祛除&nbsp
 */
function str_cut_nbsp($a)
{
    $str = str_replace(array(
        'nbsp;',
        '&amp;',
        '&nbsp',
        '&amp;nbsp;'
    ), ' ', $a);
    return trim($str);
}

// 取缩略图
function getcover($coverId, $width = null, $height = null, $imageTag = false)
{
    $src = 'http://' . $_SERVER['HTTP_HOST'] . get_cover($coverId, 'path', $width, $height);
    return $imageTag ? '<img src="' . $src . '" />' : $src;
}

/**
 * 将图片路径替换为 coverid
 */
function pathToCoverid($path)
{
    $file = trim($path, '/');
    if (!$file) {
        return '';
    }

    if (!file_exists($file)) {
        return '';
    }

    if (!in_array(strtolower(substr($path, -4)), array(
        '.jpg',
        '.png',
        '.gif',
        'jpeg'
    ))) {
        return '';
    }

    $md5 = md5_file($file);
    $md5File = M('picture')->where(array(
        'md5' => $md5
    ))->find();
    if ($md5File) {
        return $md5File['id'];
    }

    return M('picture')->data(array(
        'path' => $path,
        'status' => 1,
        'create_time' => NOW_TIME,
        'md5' => $md5,
        'sha1' => sha1_file($file)
    ))->add();
}

/**
 * 定时任务进程未启动时通过 ajax 启动计划任务
 */
function jscron()
{
    if (!CRON_CLI) {
        $cronStatus = o('cron')->status();
        return $cronStatus['deamon'] ? '' : '<script src="' . U('/cron/index/js', '', true, true) . '"></script>';
    }
    return '';
}


/**
 * 计算两组经纬度坐标 之间的距离
 * params ：lat1 纬度1； lng1 经度1； lat2 纬度2； lng2 经度2； len_type （1:m or 2:km);
 * return m or km
 */
function distance($lng1, $lat1, $lng2, $lat2, $len_type = 2, $decimal = 2)
{
    $radLat1 = $lat1 * 3.1415926 / 180.0;
    $radLat2 = $lat2 * 3.1415926 / 180.0;
    $a = $radLat1 - $radLat2;
    $b = ($lng1 * 3.1415926 / 180.0) - ($lng2 * 3.1415926 / 180.0);
    $s = 2 * asin(sqrt(pow(sin($a / 2), 2) + cos($radLat1) * cos($radLat2) * pow(sin($b / 2), 2)));
    $s = $s * 6378.137;
    $s = round($s * 1000);
    if ($len_type-- > 1) {
        $s /= 1000;
    }
    return round($s, $decimal);
}

/**
 * 过滤数据
 *
 * @param string $data
 * @param string $rules
 * @param string $throw
 * @throws Exception
 */
function filter(&$data = '', $rules = '', $throw = true)
{
    try {
        return $data = \Kcdns\Service\Util\Validate::getInstance()->check($data, $rules);
    } catch (\Exception $e) {
        $error = \Kcdns\Service\Util\Validate::getInstance()->error;
        $message = $error['message'] ?: (APP_DEBUG ? $e->getMessage() : '系统繁忙[F]');
        $log[] = $e->getMessage();

        // 调试日志记录过滤器调用代码及参数, 便于排查
        $trace = debug_backtrace();
        for ($i = count($trace) - 1; $i > -1; $i--) {
            $v = $trace[$i];
            if ($v['function'] === 'filter') {
                $handle = fopen($v['file'], 'r');
                $errorFileLine = 1;
                while (!feof($handle)) {
                    $row = trim(fgets($handle));
                    if ($v['line'] == $errorFileLine++) {
                        $log[] = "                    * FILE : {$v['file']}({$v['line']})";
                        $log[] = "                    * CODE : $row";
                        $log[] = "                    * ARGS : " . implode(',', $v['args']);
                        break (2);
                    }
                }
            }
        }

        if ($throw) {
            throw new \InvalidParamException($message);
        }
        return $data = null;
    }
}

/**
 * 下载微信图片到本地, 将 mediaId 替换为 Picture.id
 *
 * @param unknown $mediaId
 */
function mediaToLocal($mediaId)
{
    if (is_int($mediaId) && M('picture')->find($mediaId)) {
        return $mediaId;
    }
    $id = M('picture')->where(['url' => $mediaId])->getField('id');
    if (0 < $id) {
        return $id;
    }

    $ext = '.jpg';
    $filename = "./Uploads/Picture/" . date('Y-m') . '/' . $mediaId . $ext;

    $dir = dirname($filename);
    file_exists($dir) or mkdir($dir, 0777, true);

    $fp = fopen($filename, 'wb');
    if (!$fp) {
        KCSLog::WARN('open file faild ' . $filename);
        return false;
    }
    fwrite($fp, OE('wechat')->load()->getMedia($mediaId));
    fclose($fp);
    return M('picture')->data(array(
        'path' => trim($filename, '.'),
        'md5' => md5($filename),
        'sha1' => sha1_file($filename),
        'url' => trim($filename, '.'),
        'status' => 1
    ))->add();
}

/**
 * 将库里图片ID 转换成 id=src,id=src 适用于前端JS上传插件适用的格式
 */
function imgIdToPath($ids)
{
    if (!$ids)
        return "";

    $response = "";

    // ID为数组格式或者逗号隔开多图上传
    if (is_array($ids) || strpos($ids, ',') !== false) {
        $ids = is_array($ids) ?: explode(',', $ids);
        foreach ($ids as $id) {
            $response[] = "{$id}=" . get_cover($id, 'path');
        }
        return implode(',', $response);
    }

    // 单ID
    return "{$ids}=" . get_cover($ids, "path");
}

/**
 * 获取gateWayIp
 */
function getServerIp()
{
    $ss = exec('/sbin/ifconfig eth2 | sed -n \'s/^ *.*addr:\\([0-9.]\\{7,\\}\\) .*$/\\1/p\'', $arr);
    $ret = $arr[0];

    return $ret;
}

function getDomainIp($domain)
{
    $ss = exec('/usr/bin/getent hosts ' . $domain . ' | awk \'{print $1}\'', $arr);
    $ret = $arr[0];
    return $ret;
}

//获取小数不四舍五入
function get_decimal($num, $decimal = 2)
{
    $arr = explode('.', strval($num));
    $num = join('.', [$arr[0], substr($arr[1], 0, $decimal)]);
    return sprintf("%.{$decimal}f", $num);
}

//获取列表类型的配置
function get_list_config($cfg_name, $all = false)
{
    $arr = json_decode(C($cfg_name), true);
    $result = [];
    foreach ($arr as $row) {
        $result[$row['type']] = $all ? $row : $row['label'];
    }
    return $result;
}